pub mod route_t {
    use std::fmt::Display;

    use yew_router::prelude::*;
    use yew::prelude::*;

    #[derive(Clone, Debug, PartialEq, Eq)]
    struct Default {
        s: String
    }
    impl Display for Default {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            write!(f, "alie ?!?!?{}", self.s)
        }
    }
    impl std::str::FromStr for Default {
        type Err = ();

        fn from_str(s: &str) -> Result<Self, Self::Err> {
            let def = Default { s: s.to_string() };
            Ok(def)
        }
    }
    #[derive(Clone, PartialEq, Routable)]
    enum Route {
        #[at("/")]
        Home,
        #[at("/secure")]
        Secure,
        #[at("/404")]
        NotFound,
        #[at("/post/:id")]
        Post {id: String},
        #[at("/default/:s")]
        Default {s: Default}
    }
    #[function_component(Secure)]
    fn secure() -> Html {
        let history = use_history().unwrap();
        let onclick = Callback::once(move |_| history.push(Route::Home));
        html! {
            <div>
                <h1>{"Secure"}</h1>
                <button {onclick}>{"Go Home"}</button>
            </div>
        }
    }
    fn switch(routes: &Route) -> Html {
        match routes {
            Route::Home => html! {
                <h1>{"Home"}</h1>
            },
            Route::Secure => html! {
                <Secure/>
            } ,
            Route::NotFound => html! {
                <h1>{"404"}</h1>
            },
            Route::Post { id } => html!{
                <p>{format!("You are looking at Post {}", id)}</p>
            },
            Route::Default { s } => html!{
                <p>{s}</p>
            },
        }
    }

    #[function_component(NavItem)]
    pub fn nav_items() -> Html {
        let history = use_history().unwrap();
        let go_home_button = {
            let history = history.clone();
            let onclick = Callback::once(move |_| history.push(Route::Home));
            html! {
                <button {onclick}>{"Home"}</button>
            }
        };
        let go_to_first_post_button = {
            // if in the Component :
            // let history = ctx.link().history().unwrap;
            let history = history.clone();
            let onclick = Callback::once(move |_| history.push(Route::Post{id: "first-post".to_string()}));
            html! {
                <button {onclick}>{"First Post"}</button>
            }
        };
        let go_secure_button = {
            let history = history.clone();
            let onclick = Callback::once(move |_| history.push(Route::Secure));
            html! {
                <button {onclick}>{"Secure"}</button>
            }
        };
        html!{
            <>
                {go_home_button}
                <br/>
                {go_to_first_post_button}
                <br/>
                {go_secure_button}
                <br/>
            </>
        }
    }
    #[derive(Clone, Routable, PartialEq)]
    enum MainRoute {
        #[at("/")]
        Home,
        #[at("/news")]
        News,
        #[at("/contact")]
        Contact,
        #[at("/settings/:s")]
        Settings,
        #[not_found]
        #[at("/404")]
        NotFound
    }
    #[derive(Clone, Routable, PartialEq)]
    enum SettingsRoute {
        #[at("/settings/profile")]
        Profile,
        #[at("/settings/friends")]
        Friends,
        #[at("/settings/theme")]
        Theme,
        #[at("/settings/404")]
        NotFound,
    }
    fn switch_main(route: &MainRoute) -> Html {
        match route {
            MainRoute::Home => html!{
                <h1>{"Home"}</h1>
            },
            MainRoute::News => html!{
                <h1>{"News"}</h1>
            },
            MainRoute::Contact => html!{
                <h1>{"Contact"}</h1>
            },
            MainRoute::Settings => html!{
                <Switch<SettingsRoute> render={Switch::render(switch_settings)}/>
            },
            MainRoute::NotFound => html!{
                <h1>{"Not Found"}</h1>
            },
        }
    }
    fn switch_settings(route: &SettingsRoute) -> Html {
        match route {
            SettingsRoute::Profile => html!{
                <h1>{"Profile"}</h1>
            },
            SettingsRoute::Friends => html!{
                <h1>{"Friends"}</h1>
            },
            SettingsRoute::Theme => html!{
                <h1>{"Theme"}</h1>
            },
            SettingsRoute::NotFound => html!{
                <Redirect<MainRoute> to={MainRoute::NotFound}/>
            },
        }
    }
    #[function_component(Main)]
    pub fn app() -> Html {
        html! {
            <div>
                // this need add to BrowserRouter
                // <Redirect<Route> to={Route::Login}/>
                <BrowserRouter>
                    <Switch<Route> render={Switch::render(switch)}/>
                    <Link<Route> to={Route::Home}>{"click here to go Home"}</Link<Route>>
                    <br />
                    <Link<Route> to={Route::Post {id: "new".to_string()}}>{"new post"}</Link<Route>>
                    <br />
                    <NavItem/>
                    <br />
                    <Switch<MainRoute> render={Switch::render(switch_main)}/>
                </BrowserRouter>
            </div>
        }
    }
}